home *** CD-ROM | disk | FTP | other *** search
- TITLE C - Initiate execution of a Lattice C program
- SUBTTL Copyright 1982 by Lattice, Inc.
- NAME C
- INCLUDE DOS.MAC
- ;**
- ;
- ; name C -- initiate execution of C program
- ;
- ; description This is the main module for a C program on the
- ; MS-DOS implementation. It initializes the segment
- ; registers, sets up the stack, and calls the C main
- ; function _main with a pointer to the remainder of
- ; the command line.
- ;
- ; Also defined in this module: the exit entry point
- ; XCEXIT, and the stack overflow entry XCOVF.
- ;
- ;**
- IF S8086
- PGROUP GROUP BASE,PROG
- BASE SEGMENT WORD PUBLIC 'PROG'
- DW 0
- BASE ENDS
- ENDIF
-
- IF P8086
- BASE SEGMENT WORD
- DW 1
- BASE ENDS
- ENDIF
-
- IF D8086
- CGROUP GROUP BASE,CODE
- BASE SEGMENT WORD PUBLIC 'CODE'
- DW 2
- BASE ENDS
- ENDIF
-
- IF L8086
- BASE SEGMENT WORD
- DW 3
- BASE ENDS
- ENDIF
-
- IF LPROG
- EXTRN _MAIN:FAR
- ECODE EQU 4 ;offset of error code for XCEXIT
- ELSE
- ECODE EQU 2 ;offset of error code for XCEXIT
- ENDIF
-
- DGROUP GROUP DATA,STACK
-
-
- ;
- ; The data segment defines locations which contain the offsets
- ; of the base and top of the stack.
- ;
- DATA SEGMENT PARA PUBLIC 'DATA'
- EXTRN _STACK:WORD
- PUBLIC _VER,_TOP,_BASE,_INAME,_ONAME,_PSP,_MBASE,_MNEXT,_MSIZE
- NULL DW 0
- _VER DB "Lattice C 2.00"
- _TOP DW 0 ; top of stack (relative to SS)
- _BASE DW 0 ; base of stack (relative to DS)
- _INAME DB 32 DUP(0) ; input file name
- _ONAME DB 32 DUP(0) ; output file name
- _PSP DD 0 ; program segment prefix pointer
- IF LDATA
- _MBASE DD 0 ; base of memory pool
- _MNEXT DD 0 ; next available memory location
- ELSE
- _MBASE DW 0 ; base of memory pool
- _MNEXT DW 0 ; next available memory location
- ENDIF
- _MSIZE DD 0 ; number of bytes left in pool
- IF MSDOS EQ 2
- _ENV DD 0 ; pointer to environment
- ENDIF
- STKERR DB "Invalid stack size",0DH,0AH,"$"
- NAMERR DB "Invalid I/O redirection",0DH,0AH,"$"
- MEMERR DB "Insufficient memory",0DH,0AH,"$"
- OVFERR DB "*** STACK OVERFLOW ***",0DH,0AH,"$"
- DATA ENDS
- ;
- ; The stack segment is included to prevent the warning from the
- ; linker, and also to define the base (lowest address) of the stack.
- ;
- STACK SEGMENT STACK 'DATA'
- SBASE DW 128 DUP (?)
- STACK ENDS
- STKMIN EQU 512 ; minimum stack size
-
- TAB EQU 09H ; tab character
- ;
- ; The main program must set up the initial segment registers
- ; and the stack pointer, and set up a far return to the MS-DOS
- ; exit point at ES:0. The command line bytes from the program
- ; segment prefix are moved onto the stack, and a pointer to
- ; them supplied to the C main module _main (which calls main).
- ;
- IF S8086
- PROG SEGMENT BYTE PUBLIC 'PROG'
- ASSUME CS:PGROUP
- ENDIF
-
- IF D8086
- CODE SEGMENT BYTE PUBLIC 'CODE'
- ASSUME CS:CGROUP
- ENDIF
-
- IF P8086
- _CODE SEGMENT BYTE
- ASSUME CS:_CODE
- ENDIF
-
- IF L8086
- _PROG SEGMENT BYTE
- ASSUME CS:_PROG
- ENDIF
-
- ASSUME DS:DGROUP
-
- IF LPROG EQ 0
- EXTRN _MAIN:NEAR
- ENDIF
-
- PUBLIC C
- C PROC FAR
- CLI
- MOV AX,DGROUP ; set ds base
- MOV DS,AX
- MOV AX,STACK
- MOV SS,AX ; set ss base
- MOV SP,256 ; temporarily set stack pointer
- STI
- MOV AX,OFFSET DGROUP:SBASE ; set _BASE to top of data
- MOV _BASE,AX
- MOV _PSP+2,ES ; set up pointer to prog seg prefix
- IF MSDOS EQ 2
- MOV AX,ES:[2CH]
- MOV _ENV+2,AX ; set up pointer to environment
- ENDIF
- ;
- ; Examine command line
- ;
- MOV SI,80H ; check command line
- MOV CL,ES:[SI]
- XOR CH,CH
- JCXZ M12 ; branch if null
- M1: INC SI ; scan for first arg
- MOV AL,ES:[SI]
- IF MSDOS EQ 1
- CMP AL,'<'
- JE M2 ; branch if input file name
- CMP AL,'>'
- JE M3 ; branch if output file name
- ENDIF
- CMP AL,'='
- JE M4 ; branch if stack size
- CMP AL,' '
- JE M11 ; branch if white space
- CMP AL,TAB
- JNE M12 ; branch if normal arg
- M11: DEC CX
- JG M1
- XOR CX,CX
- M12: JMP M5 ; branch if no args found
- IF MSDOS EQ 1
- ;
- ; Get input file name
- ;
- M2: MOV DI,OFFSET DGROUP:_INAME
- JMP M31
- ;
- ; Get output file name
- ;
- M3: MOV DI,OFFSET DGROUP:_ONAME
- ;
- ; Save file name in data area
- ;
- M31: XOR AH,AH
- M32: DEC CX
- JZ M33
- INC SI
- MOV AL,ES:[SI]
- CMP AL,' '
- JZ M33
- CMP AL,TAB
- JZ M33
- MOV DS:[DI],AL
- INC DI
- INC AH
- CMP AH,32
- JE M34
- JMP M32
- M33: MOV BYTE PTR DS:[DI],0
- JMP M11
- M34: MOV DX,OFFSET DGROUP:NAMERR
- JMP ABORT
- ENDIF
- ;
- ; Get stack size from command line
- ;
- M4: XOR BX,BX ; get stack size arg
- M41: DEC CX
- JZ M42
- INC SI
- MOV AL,ES:[SI]
- CMP AL,' '
- JE M42
- CMP AL,TAB
- JE M42
- SUB AL,'0'
- JL M43
- CMP AL,9
- JG M43
- ADD BX,BX
- JC M43
- MOV DX,BX
- ADD BX,BX
- JC M43
- ADD BX,BX
- JC M43
- ADD BX,DX
- JC M43
- XOR AH,AH
- ADD BX,AX
- JC M43
- JMP M41
- M42: OR BX,BX
- JZ M43 ; branch if stack size arg is null
- MOV _STACK,BX
- JMP M11
- M43: MOV DX,OFFSET DGROUP:STKERR
- JMP ABORT
- ;
- ; Set up the stack
- ;
- M5: MOV BX,_STACK ; get stack size
- SHR BX,1 ; make size even
- ADD BX,BX
- CMP BX,STKMIN
- JA M51
- MOV BX,STKMIN ; use default if too small
- MOV _STACK,BX
- M51: MOV DX,ES:2 ; compute available paragraphs
- IF LDATA
- MOV AX,SS
- ELSE
- MOV AX,DS
- ENDIF
- SUB DX,AX
- TEST DX,0F000H
- JNZ M52 ; branch if greater than 64Kbytes
- SHL DX,1 ; convert to bytes
- SHL DX,1
- SHL DX,1
- SHL DX,1
- JMP M53
- M52: MOV DX,0FFF0H ; use largest value
- IF LDATA
- M53: CMP DX,BX ; check if stack will fit
- JA M55
- ELSE
- M53: MOV AX,_BASE ; check if stack will fit
- ADD AX,BX
- JC M54
- CMP DX,AX
- JA M55
- ENDIF
- M54: MOV DX,OFFSET DGROUP:MEMERR ; abort if insufficient memory
- JMP ABORT
- IF LDATA
- M55: MOV _TOP,BX ; set top-of-stack
- MOV SP,BX ; set stack pointer
- ELSE
- M55: MOV _TOP,DX ; set top-of-stack
- CLI
- MOV AX,DS
- MOV SS,AX
- MOV SP,DX ; set stack pointer
- STI
- ENDIF
- ;
- ; Set up memory allocation pointers
- ;
- MOV DX,CX ; save command byte count
- IF LDATA
- MOV AX,_TOP ; compute mem pool base segment number
- ADD AX,15
- MOV CL,4
- SHR AX,CL
- MOV BX,SS
- ADD AX,BX
- MOV _MBASE+2,AX
- MOV _MNEXT+2,AX
- MOV BX,ES:2 ; get top segment number
- SUB BX,AX ; compute memory pool size
- JBE M54 ; branch if insufficient memory
- MOV CL,4 ; compute number of bytes
- ROL BX,CL
- MOV AX,BX
- AND AX,15
- AND BX,0FFF0H
- MOV _MSIZE,BX
- MOV _MSIZE+2,AX
- ELSE
- MOV AX,_BASE ; set up memory pool for small data
- MOV _MBASE,AX
- MOV _MNEXT,AX
- MOV BX,_TOP
- SUB BX,AX
- SUB BX,_STACK
- JB M54
- MOV _MSIZE,BX
- ENDIF
- ;
- ; Put return address at top of stack
- ;
- PUSH ES ; return is to 1st word of prog prefix
- XOR AX,AX
- PUSH AX
- MOV BP,SP ; BP contains stack linkage
- ;
- ; copy command line to stack
- ;
- MOV BX,DX ; get residual command line length
- MOV CX,DX
- ADD BX,4 ;3 bytes additional, 1 for rounding
- AND BX,0FFFEH ;force even number of bytes
- SUB SP,BX ;allocate space on stack
- MOV DI,SP
- MOV BYTE PTR SS:[DI],'c' ;store dummy program name
- INC DI
- JCXZ M8 ;skip if no bytes to move
- MOV BYTE PTR SS:[DI],' '
- INC DI
- M7: MOV AL,ES:[SI] ;move bytes to stack
- MOV SS:[DI],AL
- INC SI
- INC DI
- LOOP M7
- M8: MOV BYTE PTR SS:[DI],0 ; append null byte
-
- ;
- ; set up args for _main and call it
- ;
- MOV AX,SP ; push pointer to command line
- IF LDATA
- PUSH SS
- ENDIF
- PUSH AX
- PUSH DS ; make ES same as DS
- POP ES
- CALL _MAIN ;call C main
- IF MSDOS EQ 2
- MOV AX,4C00H
- INT 21H ; exit with zero code
- ELSE
- MOV SP,BP ;restore ptr to far return
- RET ;return to MS-DOS
- ENDIF
- ;
- ; Come here to abort
- ;
- ABORT: MOV AH,9 ; print error message
- INT 21H
- IF MSDOS EQ 2
- MOV AX,4C01H
- INT 21H
- ELSE
- PUSH ES
- XOR AX,AX
- PUSH AX
- RET
- ENDIF
- C ENDP
- PAGE
- ;**
- ;
- ; name XCOVF -- terminate execution after stack overflow
- ;
- ; description This entry point is reached from a C module when its
- ; entry sequence detects a stack overflow. Control is
- ; passed to XCOVF by a direct jump.
- ;
- ;**
- PUBLIC XCOVF
- XCOVF PROC FAR
- MOV AX,_TOP
- SUB AX,4
- MOV SP,AX ; RESET STACK POINTER
- MOV DX,OFFSET DGROUP:OVFERR
- MOV AH,9
- INT 21H ; GENERATE ERROR MESSAGE
- IF MSDOS EQ 2
- MOV AX,4C01H
- INT 21H ; EXIT WITH ERROR CODE
- ELSE
- RET ; RETURN TO MS-DOS
- ENDIF
- XCOVF ENDP
- ;**
- ;
- ; name XCEXIT -- terminate execution of C program
- ;
- ; description This function terminates execution of the current
- ; program by returning to MS-DOS. The error code
- ; argument normally supplied to XCEXIT is ignored
- ; in this implementation.
- ;
- ;**
- PUBLIC XCEXIT
- XCEXIT PROC FAR
- IF MSDOS EQ 2
- MOV BP,SP
- MOV AX,[BP+ECODE] ; GET ERROR CODE
- MOV AH,4CH
- INT 21H ; EXIT
- ELSE
- MOV AX,_TOP
- SUB AX,4
- MOV SP,AX
- RET
- ENDIF
- XCEXIT ENDP
-
- ENDPS
- END C